package net.zabuchy.issue.action;
 
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.zabuchy.IssueHelper.IssueStatuses;
import net.zabuchy.IssueHelper.IssuesFilterLists;
import net.zabuchy.activities.entity.History_event;
import net.zabuchy.helper.ActivityHelper;
import net.zabuchy.helper.SessionHelper;
import net.zabuchy.issue.bo.IssueBo;
import net.zabuchy.issue.entity.Attachment;
import net.zabuchy.issue.entity.Issue;
import net.zabuchy.issue.entity.IssueDetail;
import net.zabuchy.issue.entity.IssueLink;
import net.zabuchy.issue.entity.Notification;
import net.zabuchy.iteration.entity.Iteration;
import net.zabuchy.user.bo.UserBo;
import net.zabuchy.user.entity.User;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.hibernate.mapping.Collection;
import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
 

public class IssueAction extends  ActionSupport 
	implements ServletRequestAware,ServletResponseAware{ 
 
	private static final Logger LOGGER = Logger.getLogger(IssueAction.class.getName());
 
	@Autowired
    private SessionHelper sessionBean;
	@Autowired
	private IssueBo issueBo;
	@Autowired
	private UserBo userBo;
    
	private HttpServletRequest request;
    private HttpServletResponse response;
	
    private int issueId;
	private String author;
	private boolean confirmed;
	private Date creationDate;
	private int customerId;
	private String description;
	private int estimationHours;
	private Date estimationTime;
	private String priority;
	private int projectId;
	private String status;
	private String team;
	private String title;
	private String type;
	private Iteration iteration;
	private IssueDetail issueDetail;
	private Set<History_event> history = new HashSet<History_event>(0);
	private Set<User> users = new HashSet<User>(0);
	private Set<Attachment> attachments = new HashSet<Attachment>(0);
	private Set<IssueLink> issueLinks = new HashSet<IssueLink>(0);
	private Set<Notification> notifications = new HashSet<Notification>(0);
	private Set<User> notificatedUsers = new HashSet<User>(0);
	
	/**********************************************************/	
	private int currentEffort;
	private String sourceCode;
	private String stepByStep;
	private String systemConfiguration;
	private String workaround;

	private Issue issue;
	private List<Issue> issues;
	
	private int hoursEffortPercentage;
	private int dateEffortPercentage;
	private String effortColour;
	
	private List<String> usersSystem = new ArrayList<String>(0);
	private String addedUser;
	private Integer userId;
	private Set<String> fixTypes = ActivityHelper.getFixTypes();
	private Set<String> verifyTypes = ActivityHelper.getVerifyTypes();
	
	private List<String> filterList;
	private String listChoosen;
	
	
    public String listAll() {
    	
    	if(issueBo == null) {
    		return Action.ERROR;
    	}
    	filterList = new ArrayList<String>(0);
    	fillFilterList();
    	
    	LOGGER.debug("Get all issues");
    	issues = issueBo.findAllForProjectAndIteration(sessionBean.getProjectId(), 
    			sessionBean.getActualIteration().getIterationId());
    	for(Issue issue : issues) {
    		LOGGER.debug("issueId: " + issue.getIssueId() + " attachments.size(): " + issue.getAttachments().size());
    	}
        LOGGER.debug("Issues number = " + issues.size());

    	return Action.SUCCESS;
    }
 
    public String chooseList() {
    	
    	LOGGER.debug("dupa");
    	
    	this.issues = getListIssues(listChoosen);
    	
    	return Action.SUCCESS;
    }
    
    private void fillFilterList() {
    	filterList = IssuesFilterLists.getIssuesFilterList(sessionBean.getExecutorRole());
    }
    
    private List<Issue> getListIssues(String listChoosen) {
    	LOGGER.debug("listChoosen: " + listChoosen);    	
    	List<Issue> issuesList = new ArrayList<Issue>(0);
    	
    	if(listChoosen.equals("Assigned to me")) {
    		LOGGER.debug("get assigned to me issues");
    		LOGGER.debug("userId: " + sessionBean.getExecutor().getUserId() +
    				" issues.size: " + sessionBean.getExecutor().getIssues().size());
    		for(Issue issue : sessionBean.getExecutor().getIssues()) {
    			issuesList.add(issue);
    		}
    	} else if (listChoosen.equals("Open")) {
    		LOGGER.debug("get open issues. issuesList.size: " + issuesList.size());
    		issuesList = issueBo.findAllForProjectAndIterationAndStatus(
    				sessionBean.getProjectId(),
    				sessionBean.getActualIteration().getIterationId(),
    				IssueStatuses.OPEN);
    	}
    	
    	return issuesList;
    	
    }
    
    
    public String showIssue() {
    	LOGGER.debug("start");
    	//request.setAttribute("issueId", issueId);
    	clearFields();
    	getIssue(issueId);
    	
    	List<User> tmp = userBo.findByCustomerId(sessionBean.getCustomerId());
		Iterator it = tmp.iterator();
		while(it.hasNext()) {
			User user = (User) it.next();
			usersSystem.add(user.getUsername());
		}
    	
    	//LOGGER.debug("parama from req :" + request.getAttribute("issueId"));
    	//LOGGER.debug("prawie przed");
    	return Action.SUCCESS;
    	
    }
   
	public String delete() {
		if(issueBo == null) {
			return Action.ERROR;
		}
		
		Issue issue = issueBo.findById(issueId);
		if(issue == null) {
			return Action.ERROR;
		}
		
		LOGGER.debug("Delete issue " + issue.getIssueId());
		issueBo.delete(issue);
		
        return Action.SUCCESS;
    }

	public String test() {
		
		LOGGER.debug("**********************************");
		
		return Action.SUCCESS;
	}
	
	
	private void getIssue(int issueId) {
		LOGGER.debug("Get issue with id: " + issueId);
		
		this.issue = issueBo.findById(issueId);
		this.author = issue.getAuthor();
		this.confirmed = issue.getConfirmed() == 1 ? true : false;
		this.creationDate = issue.getCreationDate();
		this.description = issue.getDescription();
		this.estimationHours = issue.getEstimationHours();
		this.estimationTime = issue.getEstimationTime();
		this.priority = issue.getPriority();
		this.status = issue.getStatus();
		this.team = issue.getTeam();
		this.title = issue.getTitle();
		this.type = issue.getType();
		this.iteration = issue.getIteration();
		this.issueDetail = issue.getIssueDetail();
		this.setHistory(issue.getHistory());
		this.users = issue.getUsers();
		this.issueLinks = issue.getIssueLinks();
		this.attachments = issue.getAttachments();
		this.notifications = issue.getNotifications();
		for(Notification notify : notifications) {
			notificatedUsers.add(userBo.findById(notify.getUserId()));
			LOGGER.debug("notificatedUsers.size: " + notificatedUsers.size());
		}
		
		this.currentEffort = issueDetail.getCurrentEffort();
		this.sourceCode = issueDetail.getSourceCode();
		this.stepByStep = issueDetail.getStepByStep();
		this.systemConfiguration = issueDetail.getSystemConfiguration();
		this.workaround = issueDetail.getWorkaround();
		
		this.hoursEffortPercentage = countEffortPercentage(estimationHours, currentEffort);

		LOGGER.debug("hoursEffortPercentage: " + hoursEffortPercentage);
	}
	
	private int countEffortPercentage(int estimationHours, int currentEffort) {
		int result = 0;
		int tmp = estimationHours - currentEffort;
		tmp = tmp * 100;
		result = tmp / estimationHours;
		if(result < 0 ) {
			result = 0;
		}
		
		if(result < 50) {
			this.effortColour = "blue";
		} else if(result > 50 && result < 75) {
			this.effortColour = "orange";
		} else if(result >  75) {
			this.effortColour = "red";
		}
		
		result = 100 - result;
		return result;
	}
	
	private void clearFields() {
		//issueId = 0;
		author = null;
		creationDate = null;
		customerId = -1;
		users = null;
		status = null;
		type = null;
		description = null;
		estimationHours = 0;
		estimationTime = null;
		priority = null;
		team = null;
		title = null;
		iteration = null;
		issueDetail = null;
		setHistory(null);
		attachments = new HashSet<Attachment>(0);
		issueLinks = new HashSet<IssueLink>(0);
		notifications = new HashSet<Notification>(0);
		
		currentEffort = 0;
		sourceCode = null;
		stepByStep = null;
		systemConfiguration = null;
		workaround = null;
	}
	
	
    public String execute() {
        return Action.SUCCESS;
    }
    
 
    public IssueBo getIssueBo() {
		return issueBo;
	}

	public void setIssueBo(IssueBo issueBo) {
		this.issueBo = issueBo;
	}
    
	public void setSessionBean(SessionHelper sessionBean) {
		this.sessionBean = sessionBean;
	}

	public SessionHelper getSessionBean() {
		return sessionBean;
	}

	


	public Integer getIssueId() {
		return issueId;
	}


	public void setIssueId(Integer issueId) {
		this.issueId = issueId;
	}


	public String getAuthor() {
		return author;
	}


	public void setAuthor(String author) {
		this.author = author;
	}


	public Date getCreationDate() {
		return creationDate;
	}


	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}


	public int getCustomerId() {
		return customerId;
	}


	public void setCustomerId(int customerId) {
		this.customerId = customerId;
	}


	public int getProjectId() {
		return projectId;
	}


	public void setProjectId(int projectId) {
		this.projectId = projectId;
	}


	public Set<User> getUsers() {
		return users;
	}


	public void setUsers(Set<User> users) {
		this.users = users;
	}


	public String getStatus() {
		return status;
	}


	public void setStatus(String status) {
		this.status = status;
	}


	public String getType() {
		return type;
	}


	public void setType(String type) {
		this.type = type;
	}

	
	 public UserBo getUserBo() {
		return userBo;
	}

	public void setUserBo(UserBo userBo) {
		this.userBo = userBo;
	}

	public boolean isConfirmed() {
		return confirmed;
	}

	public void setConfirmed(boolean confirmed) {
		this.confirmed = confirmed;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public int getEstimationHours() {
		return estimationHours;
	}

	public void setEstimationHours(int estimationHours) {
		this.estimationHours = estimationHours;
	}

	public Date getEstimationTime() {
		return estimationTime;
	}

	public void setEstimationTime(Date estimationTime) {
		this.estimationTime = estimationTime;
	}

	public String getPriority() {
		return priority;
	}

	public void setPriority(String priority) {
		this.priority = priority;
	}

	public String getTeam() {
		return team;
	}

	public void setTeam(String team) {
		this.team = team;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Iteration getIteration() {
		return iteration;
	}

	public void setIteration(Iteration iteration) {
		this.iteration = iteration;
	}

	public IssueDetail getIssueDetail() {
		return issueDetail;
	}

	public void setIssueDetail(IssueDetail issueDetail) {
		this.issueDetail = issueDetail;
	}

	/**
	 * @param history the history to set
	 */
	public void setHistory(Set<History_event> history) {
		this.history = history;
	}

	/**
	 * @return the history
	 */
	public Set<History_event> getHistory() {
		return history;
	}

	public Set<Attachment> getAttachments() {
		return attachments;
	}

	public void setAttachments(Set<Attachment> attachments) {
		this.attachments = attachments;
	}

	public Set<IssueLink> getIssueLinks() {
		return issueLinks;
	}

	public void setIssueLinks(Set<IssueLink> issueLinks) {
		this.issueLinks = issueLinks;
	}

	public Set<Notification> getNotifications() {
		return notifications;
	}

	public void setNotifications(Set<Notification> notifications) {
		this.notifications = notifications;
	}

	public Set<User> getNotificatedUsers() {
		return notificatedUsers;
	}

	public void setNotificatedUsers(Set<User> notificatedUsers) {
		this.notificatedUsers = notificatedUsers;
	}

	public int getCurrentEffort() {
		return currentEffort;
	}

	public void setCurrentEffort(int currentEffort) {
		this.currentEffort = currentEffort;
	}

	public String getSourceCode() {
		return sourceCode;
	}

	public void setSourceCode(String sourceCode) {
		this.sourceCode = sourceCode;
	}

	public String getStepByStep() {
		return stepByStep;
	}

	public void setStepByStep(String stepByStep) {
		this.stepByStep = stepByStep;
	}

	public String getSystemConfiguration() {
		return systemConfiguration;
	}

	public void setSystemConfiguration(String systemConfiguration) {
		this.systemConfiguration = systemConfiguration;
	}

	public String getWorkaround() {
		return workaround;
	}

	public void setWorkaround(String workaround) {
		this.workaround = workaround;
	}

	public void setIssueId(int issueId) {
		this.issueId = issueId;
	}

	public void setIssues(List<Issue> issues) {
		this.issues = issues;
	}

	public List<Issue> getIssues() {
		return issues;
	}
	
	public Issue getIssue() {
		return issue;
	}

	public void setIssue(Issue issue) {
		this.issue = issue;
	}

	public List<String> getUsersSystem() {
		return usersSystem;
	}

	public void setUsersSystem(List<String> usersSystem) {
		this.usersSystem = usersSystem;
	}

	public String getAddedUser() {
		return addedUser;
	}

	public void setAddedUser(String addedUser) {
		this.addedUser = addedUser;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public Set<String> getFixTypes() {
		return fixTypes;
	}

	public void setFixTypes(Set<String> fixTypes) {
		this.fixTypes = fixTypes;
	}

	public Set<String> getVerifyTypes() {
		return verifyTypes;
	}

	public void setVerifyTypes(Set<String> verifyTypes) {
		this.verifyTypes = verifyTypes;
	}

	public int getHoursEffortPercentage() {
		return hoursEffortPercentage;
	}

	public void setHoursEffortPercentage(int hoursEffortPercentage) {
		this.hoursEffortPercentage = hoursEffortPercentage;
	}

	public int getDateEffortPercentage() {
		return dateEffortPercentage;
	}

	public void setDateEffortPercentage(int dateEffortPercentage) {
		this.dateEffortPercentage = dateEffortPercentage;
	}

	public String getEffortColour() {
		return effortColour;
	}

	public void setEffortColour(String effortColour) {
		this.effortColour = effortColour;
	}

	public List<String> getFilterList() {
		return filterList;
	}

	public void setFilterList(List<String> filterList) {
		this.filterList = filterList;
	}

	public String getListChoosen() {
		return listChoosen;
	}

	public void setListChoosen(String listChoosen) {
		this.listChoosen = listChoosen;
	}

	public void setServletRequest(HttpServletRequest request){
		  this.request = request;
		  }

		  public HttpServletRequest getServletRequest(){
		  return request;
		  }

		  public void setServletResponse(HttpServletResponse response){
		  this.response = response;
		  }

		  public HttpServletResponse getServletResponse(){
		  return response;
		  }
}